import { message } from "antd";
import axios from "axios";
import { LocalStorageManager } from "../cache";
import { CommonApi } from "../apis/Common";
import { setToken } from "../pages/login/login.utils";

const localStorageManager = new LocalStorageManager();
export const request = axios.create({
  baseURL: "https://rainkai.com/api",
});

/**
 * 请求拦截器,每次请求前都会触发
 */
request.interceptors.request.use((config) => {
  const token = localStorageManager.getItem("token");
  if (token) {
    config.headers.Authorization = `${token}`;
  }
  return config;
});

/**
 * 每次使用axios发起请求后，都会触发该拦截器
 * 我们可以在这里进行统一的封装或者说对数据的处理
 * 该函数必须有返回值，返回的值就是axios这次请求实际返回的值
 * 响应拦截器
 *
 * use方法接收两个函数
 * 第一个函数接口成功后调用的函数 这个成功可以理解为http的成功或者说协议层面的成功
 * 第二个函数接口失败后调用的函数 这个失败可以理解为http的失败或者说协议层面的失败
 */
request.interceptors.response.use(
  (response) => {
    /**
     * 统一处理错误
     * 定义 只要不是1000都是错误需要提示用户
     */
    if (response.data.code !== 1000) {
      message.error(response.data.message);
      throw new Error(response.data.message);
    }

    /**
     * 统一拦截我们的数据
     * 解构处理，只返回业务层需要的数据
     */
    return response.data.data;
  },
  async (err) => {
    console.log(err);
    
    /**
     * 如果接口请求返回http状态码401
     */
    if (err.response.status === 401) {
      // 本地必须有refreshToken
      const refreshToken = localStorageManager.getItem("refreshToken");

      /**
       * 如果有则重新刷新token
       * 如果refreshToken报错则直接返回登录页
       */
      if (refreshToken && err.config.url !== '/admin/base/open/refreshToken') {
        const res = await CommonApi.refreshToken({
          refreshToken: localStorageManager.getItem('refreshToken') as string
        })
        setToken(res)
        return await request(err.config)
      }
      // 没有就代表用户需要重新登录
      window.location.href = `${window.location.origin}/login`
      message.error("请重新登录");
      return
    }
    message.error("系统繁忙,请重试");
    throw new Error("请求失败");
  }
);
